Skip to content

✨ hardware cursor positioning via text() caret#103

Draft
cowboyd wants to merge 14 commits into
mainfrom
cowboyd/text-caret
Draft

✨ hardware cursor positioning via text() caret#103
cowboyd wants to merge 14 commits into
mainfrom
cowboyd/text-caret

Conversation

@cowboyd

@cowboyd cowboyd commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Adds a caret?: number property to the text() directive. When declared, the renderer positions the terminal's native cursor at the code-point offset within the text and manages cursor visibility automatically across frames.

Motivation: building a text input on top of the renderer requires the terminal cursor to track the insertion point and disappear when no input is focused. The cell where the caret sits depends on the text's layout and wrapping — information the renderer already has and the caller does not.

While painting a synthetic caret is always a possibility, the native caret is almost always going to be preferable.

2026-06-30 18 14 03

Open questions

  • Clay emits no CLAY_RENDER_COMMAND_TYPE_TEXT for an empty string, so text("", { caret: 0 }) cannot resolve a cell and silently suppresses the cursor. Documented as a test that captures current behavior. The example works around this by rendering a single space when the field is empty — invisible against the input background, but the placeholder is not ideal. One possible fix is for the renderer to fall back to the caret's parent element's bounds, but unsure what the right call is.

  • There are lurking edge cases around padding and fractional cell widths. Need to dive into those before merging.

@pkg-pr-new

pkg-pr-new Bot commented Jun 30, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@bomb.sh/tty@103

commit: 4d7b8ca

@cowboyd cowboyd changed the title ✨ feat(term): hardware cursor positioning via text() caret ✨ hardware cursor positioning via text() caret Jun 30, 2026
@cowboyd cowboyd force-pushed the cowboyd/text-caret branch from 22a27c2 to cfc0338 Compare July 1, 2026 08:02
@cowboyd cowboyd force-pushed the cowboyd/text-caret branch from cfc0338 to 4d7b8ca Compare July 1, 2026 08:05
@codspeed-hq

codspeed-hq Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will degrade performance by 11.58%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 2 regressed benchmarks
✅ 8 untouched benchmarks
⏩ 18 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime pack large list 63.4 ms 71.9 ms -11.73%
WallTime pack complex layout 47.8 ms 53.9 ms -11.43%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing cowboyd/text-caret (4d7b8ca) with main (9de7762)2

Open in CodSpeed

Footnotes

  1. 18 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (5e253a7) during the generation of this report, so 9de7762 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant